package com.liveinstars.im.api.impl;

import com.alibaba.fastjson.JSON;
import com.baidu.unbiz.easymapper.MapperFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.liveinstars.api.dto.BatchImGetUserReq;
import com.liveinstars.api.dto.ImGetUserInfo;
import com.liveinstars.api.facade.ImUserCentreApi;
import com.liveinstars.api.im.vo.TodoVO;
import com.liveinstars.im.api.IMUserService;
import com.liveinstars.im.common.enums.*;
import com.liveinstars.im.core.service.FriendsService;
import com.liveinstars.im.core.service.TodoService;
import com.liveinstars.im.domain.dao.model.ChatServer;
import com.liveinstars.im.domain.dao.model.Friends;
import com.liveinstars.im.domain.dao.model.Todo;
import com.liveinstars.im.domain.manager.ChatGroupMemberManager;
import com.liveinstars.im.domain.manager.ChatServerManager;
import com.liveinstars.im.domain.manager.UserOnlineServerManager;
import com.liveinstars.im.entity.Msg;
import com.liveinstars.im.entity.User;
import com.liveinstars.api.im.IMUserApiService;
import com.liveinstars.api.im.query.ChatServerQuery;
import com.liveinstars.api.im.query.UserOnlineServerQuery;
import com.liveinstars.api.im.vo.UserVO;
import com.onepiece.cache.aspect.Cache;
import com.onepiece.cache.service.CacheService;
import com.liveinstars.im.api.MsgGeneratorService;
import com.liveinstars.im.corebean.MsgHelper;
import com.onepiece.shipelves.common.Result;
import com.onepiece.shipelves.common.enums.SystemExceptionEnum;
import com.onepiece.shipelves.common.exception.QuHuiRuntimeException;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

;

@Service
public class IMUserApiServiceApiImpl implements IMUserApiService, IMUserService {

    @Autowired
    private FriendsService friendsService;

    @Autowired
    private TodoService todoService;

    @Autowired
    private ChatGroupMemberManager chatGroupMemberManager;

    @Autowired
    private ChatServerManager chatServerManager;

    @Autowired
    private UserOnlineServerManager userOnlineServerManager;

    @Autowired
    MsgGeneratorService msgGeneratorService;

    @Autowired
    ImUserCentreApi imUserCentreApi;

    @Autowired
    CacheService cache;

    private static final Logger LOGGER = LoggerFactory.getLogger(IMUserApiServiceApiImpl.class);


    /**
     * 获取与我相关联的用户，好友 ，同一个群 ，同一个讨论组
     *
     * @param userId
     * @return
     */
    @Override
    public List<User> getRelateUser(Long userId) {
        List<User> list = Lists.newArrayList();
        return list;
    }

    @Override
    public TodoVO addTodo(Long fromUserId, Long toUserId, int type, Integer activityId, Long groupId, String reqMsg) {

        //代办事项添加
        Todo lastTodo = todoService.getLastTodoByActivityId(fromUserId, toUserId, type, activityId);
        if (lastTodo != null && !lastTodo.getComplete()) {
            throw new QuHuiRuntimeException(IMExceptionEnum.CHAT_GROUP_JOIN_TODO_IS_EXIST);
        }
        Todo todo = new Todo();
        todo.setUserId(toUserId);
        todo.setComplete(false);
        todo.setCreateDate(LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond());
        todo.setFromId(fromUserId);
        todo.setActivityId(activityId);
        todo.setGroupId(groupId);
        todo.setSubject(reqMsg);
        todo.setRequestMsg(reqMsg);
        todo.setType(type);
        todoService.add(todo);
        msgGeneratorService.sendTodoMessage(todo, toUserId);
        TodoVO detailDto = MapperFactory.getCopyByRefMapper().mapClass(Todo.class, TodoVO.class).register()
                .map(todo, TodoVO.class);
        return detailDto;
    }

    @Override
    public Boolean containTodo(Long userId, Integer id) {
        Todo todo = todoService.getTodoByActivityIdAndUserId(userId, id);
        return todo != null;
    }

    @Override
    public List<TodoVO> getActivityTodoList(Long userId, Integer type) {
        List<Todo> todos = todoService.listUnCompleteActivityTodoByUserId(userId);
        MapperFactory.getCopyByRefMapper().mapClass(Todo.class, TodoVO.class).register();
        List<TodoVO> todoVOS = todos.stream().map(todo -> MapperFactory.getCopyByRefMapper().map(todo, TodoVO.class)).collect(Collectors.toList());
        return todoVOS;
    }

    @Override
    public String getUserAndUpdate(Long userId, Boolean needUpdate) {
        Result<User> result = new Result<>();
        ImGetUserInfo userInfo = imUserCentreApi.imGetUserInfo(userId);
        if (userInfo != null) {
            User user = new User();
            user.setId(userInfo.getUid());
            user.setName(userInfo.getUserName());
            user.setLogo(userInfo.getLogo());
            user.setGroupId(userInfo.getGroupId());
            user.setNickName(userInfo.getNickName());
            user.setDate(userInfo.getRegdate().toString());
            result.setData(user);
        } else {
            result = IMExceptionEnum.USER_IS_NOT_EXIST.createResult();
        }
        return JSON.toJSONString(result);
    }

    @Override
    public String getUsersAndUpdate(String uids, Boolean needUpdate) {
        Result<List<User>> result = new Result<>();
        List<User> userList = Lists.newArrayList();
        String[] split = uids.split("_");
        if (split.length == 0) {
            result = IMExceptionEnum.CHAT_GROUP_LACK_OPERATION_USER.createResult();
            return JSON.toJSONString(result);
        }
        List<Long> userIds = new ArrayList<>();
        Arrays.stream(split).forEach(s -> userIds.add(Long.valueOf(s)));
        BatchImGetUserReq batchImGetUserReq = new BatchImGetUserReq();
        batchImGetUserReq.setUids(userIds);
        Result<List<ImGetUserInfo>> listResult = imUserCentreApi.batchImGetUserInfo(batchImGetUserReq);
        if(listResult.getCode().equals(com.onepiece.shipelves.common.Result.SUCCESS)) {
            List<ImGetUserInfo> userInfoList = listResult.getData();
            if (CollectionUtils.isNotEmpty(userInfoList)) {
                for (ImGetUserInfo userInfo : userInfoList) {
                    //更新本地user，logo，在用户调用获取图像的时候也会刷新
                    User user = new User();
                    user.setNickName(userInfo.getNickName());
                    user.setName(userInfo.getUserName());
                    user.setGroupId(userInfo.getGroupId());
                    user.setLogo(userInfo.getLogo());
                    user.setId(userInfo.getUid());
                    user.setDate(userInfo.getRegdate().toString());
                    userList.add(user);
                }
            }
        }
        result.setData(userList);
        return JSON.toJSONString(result);
    }

    @Override
    public String getMyTempRelation(Long userId) {
        Result<List<UserVO>> result = new Result<>();
        List<UserVO> userList = friendsService.listFriendsByUserIdAndType(userId, 2);
        if (userList != null) {
            result.setData(userList);
        } else {
            result = IMExceptionEnum.FRIEND_TEMP_IS_NOT_EXIST.createResult();
        }
        return JSON.toJSONString(result);
    }

    @Override
    public String addFriends(Long userId, Long friendsId, String requestMsg) {
        Result result = new Result();
        if(userId.equals(friendsId)){
            result = SystemExceptionEnum.ILLEGAL_REQUEST_PARAM.createResult();
            return JSON.toJSONString(result);
        }
        ImGetUserInfo userInfo = imUserCentreApi.imGetUserInfo(userId);
        ImGetUserInfo friendsInfo = imUserCentreApi.imGetUserInfo(friendsId);

        if (userInfo == null || friendsInfo == null) {
            result = SystemExceptionEnum.ILLEGAL_REQUEST_PARAM.createResult();
            return JSON.toJSONString(result);
        }

        Todo lastTodo = todoService.getLastTodoByGroupId(userId, friendsId, Todo.TODO_TYPE_ADD_FRIENDS, 0L);
        if (lastTodo != null && !lastTodo.getComplete()) {
            result = IMExceptionEnum.FRIEND_JOIN_TODO_IS_EXIST.createResult();
            return JSON.toJSONString(result);
        }

        if (friendsService.isFriends(userId, friendsId, 1)) {
            result = IMExceptionEnum.FRIEND_JOIN_USER_IS_EXIST.createResult();
            return JSON.toJSONString(result);
        }

        Todo todo = new Todo();
        todo.setUserId(friendsInfo.getUid());
        todo.setComplete(false);
        todo.setCreateDate((LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond()));
        todo.setFromId(userInfo.getUid());
        String subject = "用户[" + userInfo.getUserName() + "]请求添加您为好友！";
        todo.setSubject(subject);
        todo.setRequestMsg(requestMsg);
        todo.setGroupId(0L);
        todo.setType(Todo.TODO_TYPE_ADD_FRIENDS);

        todoService.add(todo);

        msgGeneratorService.sendTodoMessage(todo, friendsId);

        return JSON.toJSONString(result);
    }


    @Override
    public String deleteFriends(Long userId, Long friendsId) {
        Result result = new Result();
        friendsService.deleteFriends(userId, friendsId);
        // 推送删除好友通知（删除对象的通知）
        Map<String, Long> data = Maps.newHashMap();
        data.put("user_id", userId);
        Msg.Message noticeMessage = MsgHelper.newNoticeMessage(NoticeMessageTypeEnum.DELETE_FRIEND.getValue(), 0, JSON.toJSONString(data));
        msgGeneratorService.sendRoamingMessage(friendsId, PassThroughMessageTypeEnum.USER, noticeMessage);
        return JSON.toJSONString(result);
    }

    @Override
    public String dealWithTodo(Long userId, Long todoId, Boolean agreeOrNot, String handleMsg) {
        return "";
//        Result<Todo> result = new Result<>();
//        Todo todo = todoService.getById(todoId);
//        ImGetUserInfo fromUser = imUserCentreApi.imGetUserInfo(todo.getFromId());
//        ImGetUserInfo toUser = imUserCentreApi.imGetUserInfo(todo.getUserId());
//        TodoP0 todoP0 = MapperFactory.getCopyByRefMapper().mapClass(Todo.class, TodoP0.class).register()
//                .map(todo, TodoP0.class);
//        User userA = new User();
//        userA.setId(fromUser.getUid());
//        userA.setDate(fromUser.getRegdate().toString());
//        userA.setLogo(fromUser.getLogo());
//        userA.setGroupId(fromUser.getGroupId());
//        userA.setName(fromUser.getUserName());
//        userA.setNickName(fromUser.getNickName());
//
//        User userB = new User();
//        userB.setId(toUser.getUid());
//        userB.setDate(toUser.getRegdate().toString());
//        userB.setLogo(toUser.getLogo());
//        userB.setGroupId(toUser.getGroupId());
//        userB.setName(toUser.getUserName());
//        userB.setNickName(toUser.getNickName());
//        todoP0.setFrom(userA);
//        todoP0.setUser(userB);
//        if (agreeOrNot) {
//            if (todo != null && !todo.getComplete()) {
//                switch (todo.getType()) {
//                    // 加好友
//                    case Todo.TODO_TYPE_ADD_FRIENDS:
//                        // 添加好友
//                        friendsService.makeFriends(todo.getFromId(), todo.getUserId(), 1);
//                        // 推送消息
//                        msgGeneratorService.sendNotifyMessage(new NotifyData(todo.getUserId(), todo.getFromId(), toUser.getUserName() + "加您为好友！", 0L));
//                        // 推送添加好友通知
//                        Map<String, Long> data = Maps.newHashMap();
//                        data.put("user_id", todo.getUserId());
//                        Msg.Message noticeMessage = MsgHelper.newNoticeMessage(NoticeMessageTypeEnum.ADD_FRIEND.getValue(), 0, JSON.toJSONString(data));
//                        msgGeneratorService.sendRoamingMessage(todo.getFromId(), PassThroughMessageTypeEnum.USER, noticeMessage);
//                        // 更新代办状态
//                        todoService.finishTodo(todoId, "成功添加成好友。", agreeOrNot);
//                        todo.setAgree(agreeOrNot);
//                        todo.setComplete(true);
//                        break;
//                    // 加群
//                    case Todo.TODO_TYPE_JOIN_GROUP:
//                        List<ChatGroupMember> list = Lists.newArrayList();
//                        ChatGroupMember chatGroupMember = new ChatGroupMember();
//                        chatGroupMember.setUserId(fromUser.getUid());
//                        chatGroupMember.setChatGroupId(todo.getGroupId());
//                        chatGroupMember.setGroupType(ChatGroupTypeEnum.CHAT_CIRCLE.getValue());
//                        list.add(chatGroupMember);
//                        chatGroupMemberManager.batchSaveMember(list, (long) todo.getGroupId());
//                        todoService.finishTodo(todoId, "已添加为群成员。", agreeOrNot);;
//                        msgGeneratorService.sendNotifyMessage(new NotifyData(userId, 0L, fromUser.getUserName() + "加入圈子！", todo.getGroupId()));
//                        // 推送添加群组通知
//                        Map<String, Long> joinGroupData = Maps.newHashMap();
//                        joinGroupData.put("group_id", todo.getGroupId());
//                        Msg.Message noticeMessage2 = MsgHelper.newNoticeMessage(NoticeMessageTypeEnum.JOIN_CHAT_GROUP.getValue(), 0, JSON.toJSONString(joinGroupData));
//                        msgGeneratorService.sendRoamingMessage(todo.getFromId(), PassThroughMessageTypeEnum.USER, noticeMessage2);
//                        todo.setAgree(agreeOrNot);
//                        todo.setComplete(true);
//                        break;
//                    default:
//                        break;
//                }
//            }
//        } else {
//            todoService.finishTodo(todoId, "手机处理，已拒绝。", agreeOrNot);
//            todo.setAgree(agreeOrNot);
//            todo.setComplete(true);
//        }
//
//        if(todoP0 != null && todoP0.getUser() != null) {
//            ImGetUserInfo userInfo = imUserCentreApi.imGetUserInfo(todoP0.getUser().getId());
//            todoP0.getUser().setLogo(userInfo.getLogo());
//            todoP0.getUser().setName(userInfo.getUserName());
//            todoP0.getUser().setNickName(userInfo.getUserName());
//            todoP0.getUser().setDate(userInfo.getRegdate().toString());
//        }
//        result.setData(todo);
//        return JSON.toJSONString(result);
    }


    @Override
    public String shieldUser(Long userId, Long toId) {
        Result result = new Result();
        //屏蔽对方，先查对方是否是好友，是则屏蔽，不是，查是不是临时关系，是则屏蔽，不是就donothing
        try {
            friendsService.shieldFriends(userId, toId);
        } catch (Exception e) {
           result = SystemExceptionEnum.UN_KNOW_ERROR.createResult();
        }
        return JSON.toJSONString(result);
    }

    @Override
    public String remarkUser(Long userId, Long toId, String remark) {
        Result result = new Result();
        ImGetUserInfo userInfo = imUserCentreApi.imGetUserInfo(toId);
        if (userInfo == null) {
            result = IMExceptionEnum.USER_IS_NOT_EXIST.createResult();
        } else {
            try {
                Friends friends = new Friends();
                friends.setRemarkName(remark);
                friendsService.updateFriendsByUserIdAndFriendId(userId, toId, friends);
            } catch (Exception e) {
                result = SystemExceptionEnum.UN_KNOW_ERROR.createResult();
            }
        }
        return JSON.toJSONString(result);
    }

    @Cache(seconds = 30 * 60)
    @Override
    public String iplist() {
        Result<List<ChatServer>> result = new Result<>();
        ChatServerQuery chatServerQuery = new ChatServerQuery();
        chatServerQuery.setOnline(true);
        List<ChatServer> chatServers = chatServerManager.listByQuery(chatServerQuery);
        List<ChatServer> recommendOnlineServers = Lists.newArrayList();
        int num = 5000;
        if (CollectionUtils.isEmpty(chatServers)) {
            result = SystemExceptionEnum.UN_KNOW_ERROR.createResult();
        } else {
            for (; ; ) {
                for (int i = 0; i < chatServers.size(); i++) {
                    ChatServer chatServer = chatServers.get(i);
                    UserOnlineServerQuery query = new UserOnlineServerQuery();
                    query.setChatServerId(chatServer.getId());
                    int count = userOnlineServerManager.countByQuery(query);
                    if (count < num) {
                        recommendOnlineServers.add(chatServer);
                    }
                }
                if (CollectionUtils.isNotEmpty(recommendOnlineServers)) {
                    result.setData(recommendOnlineServers);
                    return JSON.toJSONString(result);
                }
                num *= 2;
            }
        }
        //如果在第一个服务器上登陆的用户数大于5000，循环获取小于5000的服务器ip，返回推荐服务器，为了避免用户消息太多服务器转发。
        return JSON.toJSONString(result);
    }

    @Override
    public Result<List<UserVO>> getRecommendUsers(Long userId) {
        //TODO 待删除
        return null;
    }

    @Override
    public Result<List<UserVO>> listServiceUser() {
        List<UserVO> list = Lists.newArrayList();
        UserVO vo = new UserVO();
        vo.setId(SpecialUserEnum.IM_ASSISTANT.getId());
        vo.setName(SpecialUserEnum.IM_ASSISTANT.getName());
        vo.setNickName(SpecialUserEnum.IM_ASSISTANT.getName());
        vo.setLogo(SpecialUserEnum.IM_ASSISTANT.getLogo());
        vo.setMobile("");
        list.add(vo);

        vo = new UserVO();
        vo.setId(SpecialUserEnum.NEW_ACTIVITY.getId());
        vo.setName(SpecialUserEnum.NEW_ACTIVITY.getName());
        vo.setNickName(SpecialUserEnum.NEW_ACTIVITY.getName());
        vo.setLogo(SpecialUserEnum.NEW_ACTIVITY.getLogo());
        vo.setMobile("");
        list.add(vo);

        vo = new UserVO();
        vo.setId(SpecialUserEnum.NEWS_FLASH.getId());
        vo.setName(SpecialUserEnum.NEWS_FLASH.getName());
        vo.setNickName(SpecialUserEnum.NEWS_FLASH.getName());
        vo.setLogo(SpecialUserEnum.NEWS_FLASH.getLogo());
        vo.setMobile("");
        list.add(vo);
        Result<List<UserVO>> result = new Result<>();
        result.setData(list);
        return result;
    }

    @Override
    public String getRelateUserJson(Long userId) {
        Result<List<User>> result = new Result<>();
        List<User> users = getRelateUser(userId);
        if (CollectionUtils.isNotEmpty(users)) {
            result.setData(users);
        } else {
            result = IMExceptionEnum.USER_IS_NOT_EXIST.createResult();
        }
        return JSON.toJSONString(result);
    }

    @Override
    public Result<Boolean> isFriend(Long userId, Long myId) {
        Result<Boolean> result = new Result<>();
        Boolean isFriend = friendsService.isFriends(userId, myId, 1);
        result.setData(isFriend);
        return result;
    }

    @Override
    public Result<Boolean> isShield(Long userId, Long myId) {
        Result<Boolean> result = new Result<>();

        //屏蔽对方，先查对方是否是好友，是则屏蔽，不是，查是不是临时关系，是则屏蔽，不是就donothing
        Friends friends = friendsService.getFriendsByUserIdAndFriendId(myId, userId);
        if (friends != null) {
            result.setData(friends.getShield());
        } else {
            result.setData(false);
        }
        return result;
    }

    @Override
    public Result<String> getRemarkName(Long userId, Long myId) {
        Result<String> result = new Result<>();
        Friends friends = friendsService.getFriendsByUserIdAndFriendId(myId, userId);
        if (friends != null) {
            result.setData(friends.getRemarkName());
        }
        return result;
    }
}
